package stv5.handlers;

import java.util.List;

import stv5.Episode;
import stv5.Request;
import stv5.Response;
import stv5.Series;
import stv5.Settings;
import stv5.abstracted.RequestHandler;
import us.danlib.templating.Template;
import us.danlib.templating.Templator;

public class MediaHandler extends RequestHandler {
	
	private Settings mySettings;
	private Templator browseTpl, viewTpl;

	public MediaHandler(Settings mySettings) {
		this.mySettings = mySettings;
		browseTpl = new Templator("template/browse.tpl");
		viewTpl = new Templator("template/view.tpl");
	}

	@Override
	protected boolean handle(Request request, Response response) {
		response.setContentType("text/html");
		switch (request.getType()) {
			case BROWSE:
				response.setBody( browse(request) );
			break;
			case VIEW:
				response.setBody( view(request) );
			break;
			default:
				// unhandled type
				return false;
		}
		return true;
	}
	
	private String browse(Request request) {
		if (!request.hasVar("id"))
			return null;
		
		int seriesId = Integer.parseInt(request.getVar("id"));
		if (!mySettings.hasSeries(seriesId)) 
			return null;		
				
		Series currSeries = mySettings.getSeries(seriesId);
		List<Episode> episodes = mySettings.getEpisodes(currSeries);		
		Episode next = mySettings.getNextFor(currSeries);
		Episode last = mySettings.getLastFor(currSeries);
		
		Template t = browseTpl.createTemplate(
				"SERIES_NAME", currSeries.getName(),
				"HOME_LINK", "../../"
		);
		if (episodes == null || episodes.size() == 0) {
			t.addGlobalVar("ERROR", "1");
			t.addGlobalVar("ERROR_LINK", "../../settings/view/?page=rebuild");
			return t.render();
		}
		if (next != null) {
			t.addGlobalVar("NEXT_LINK", currSeries.getNextLink());
			t.addGlobalVar("NEXT_NAME", next.getName());
		} else if (last != null) 
			t.addGlobalVar("LAST_NAME", last.getName());
		
		// add the episode list
		int epNum = 0;
		for (Episode e : episodes) {
			t.addClass("episode",
					"SAVE_LINK", 
						"../view/?id="+currSeries.getId()+"&amp;ep="+epNum+"&amp;save=1",
					"NOSAVE_LINK",
						"../view/?id="+currSeries.getId()+"&amp;ep="+epNum,
					"NAME", e.getName()
			);
			epNum++;
		}
		
		return t.render();
	}

	/*
	private String oldbrowse(Request request) {		
		if (!request.hasVar("id"))
			return null;
		
		int seriesId = Integer.parseInt(request.getVar("id"));
		if (!mySettings.hasSeries(seriesId)) 
			return null;		
				
		Series currSeries = mySettings.getSeries(seriesId);
		List<Episode> episodes = mySettings.getEpisodes(seriesId);
		int nextId = currSeries.getLastPlay()+1;
		Episode next = (nextId < episodes.size()) ? episodes.get(nextId) : null;
		
		StringBuffer buff = new StringBuffer();
		buff.append(getStandardHeaders("STv5 - "  + currSeries.getName()));
		buff.append("<h3>Browse: <i>" + currSeries.getName() + "</i></h3>\n");
		
		if (episodes.size() == 0) {
			buff.append("<div class=\"error\">ERROR: Did not find any episodes for this series."
					+" You may want to go to settings and " +
					"<a href=\"../../settings/view/?page=rebuild\">rebuild the database</a>.");
			buff.append(getStandardFooters());
			return buff.toString();
		}		
		
		if (next != null) {
			buff.append("<p>Continue to next: <a href=\"../view/?id="+currSeries.getId()
					+"&amp;ep="+nextId+"&amp;save=1\">"+next.getName()+"</a></p>\n");
		} else {
			buff.append("<p>Could not find next episode. (Last was: " 
					+ episodes.get(nextId-1).getName() + ")</p>\n");
		}
		
		buff.append("<table class=\"episode-list\">\n");
		int epNum = 0;
		for (Episode e : episodes) {
			buff.append("<tr><td><a href=\"../view/?id="+currSeries.getId()
					+"&amp;ep="+epNum+"&amp;save=1\">"+e.getName()
					+"</a></td><td><a href=\"../view/?id="+currSeries.getId()
					+"&amp;ep="+epNum+"\">Just view, don't save</a></td></tr>\n");
			epNum++;
		}
		buff.append("</table>\n");
		buff.append(getNavigation());
		buff.append(getStandardFooters());
		return buff.toString();
	}*/
	
	private String view(Request request) {
		if (!(request.hasVar("id") && request.hasVar("ep")))
			return null;
		
		int seriesId = Integer.parseInt(request.getVar("id"));
		if (!mySettings.hasSeries(seriesId)) 
			return null;		
				
		Series currSeries = mySettings.getSeries(seriesId);
		List<Episode> episodes = mySettings.getEpisodes(seriesId);
		boolean doSave = request.hasVar("save") && "1".equals(request.getVar("save"));
		int epId = Integer.parseInt( request.getVar("ep") );
		Episode theEp = (epId < episodes.size()) ? episodes.get(epId) : null;
		Episode next = (epId+1 < episodes.size()) ? episodes.get(epId+1) : null;
		
		Template t = viewTpl.createTemplate(
				"EPISODE_NAME", (theEp != null) ? theEp.getName() : "(error)",
				"SERIES_NAME", currSeries.getName(),
				"EPISODE_LINK", (theEp != null) ? theEp.getLink() : "",
				"SERIES_LINK", "../browse/?id="+currSeries.getId(), 
				"HOME_LINK", "../../"
		);
		if (theEp == null)
			t.addGlobalVar("ERROR", "1");
		if (next != null) {
			t.addGlobalVar("NEXT_LINK", "?id="+seriesId+"&ep="+(epId+1)+(doSave?"&save=1":""));
			t.addGlobalVar("NEXT_NAME", next.getName());
		}
		if (doSave) {
			currSeries.setLastPlay( epId );
			currSeries.updateLastView();
			mySettings.updateSeries(currSeries);
			t.addGlobalVar("SAVED", "1");
	    }
		
		if (request.isLocal()) {
			// maybe we want to watch it on the server computer!			
			String localLoc = mySettings.getLocalForEpisode(currSeries, theEp);
			t.addGlobalVar("LOCAL", "1");
			if (!request.hasVar("local") && localLoc != null) {
				// the LINK to load it locally
				t.addGlobalVar("EPISODE_LOCAL_LINK", "?id="+seriesId+"&ep="+
						(epId)+"&local=1&save="+(doSave?1:0));				
			} else if (request.hasVar("local")) {
				
				t.addGlobalVar("LOCAL_LOADING", "1");						
				if (localLoc == null || !loadLocalFile(localLoc)) {
					// if the next if doesn't get hit, then
					//  we couldn't find the file
					t.addGlobalVar("LOCAL_LOADING_ERROR", "1");
					
					if (localLoc != null) {
						// couldn't start player
						t.addGlobalVar("LOCAL_LOADING_ERROR_PLAYER", "1");
						t.addGlobalVar("EPISODE_LOCAL", localLoc);
						t.addGlobalVar("PLAYER", mySettings.getLocalPlayerLoc());
					}
				}	
			}
		}		
		
		return t.render();
	}
	
	/*
	private String oldview(Request request) {
		if (!(request.hasVar("id") && request.hasVar("ep")))
			return null;
		
		int seriesId = Integer.parseInt(request.getVar("id"));
		if (!mySettings.hasSeries(seriesId)) 
			return null;		
				
		Series currSeries = mySettings.getSeries(seriesId);
		List<Episode> episodes = mySettings.getEpisodes(seriesId);
		boolean doSave = request.hasVar("save") && "1".equals(request.getVar("save"));
		int epId = Integer.parseInt( request.getVar("ep") );
		Episode theEp = (epId < episodes.size()) ? episodes.get(epId) : null;
		Episode next = (epId+1 < episodes.size()) ? episodes.get(epId+1) : null;
		
		StringBuffer buff = new StringBuffer();	
		buff.append(getStandardHeaders("STv5 - " + 
				(request.hasVar("local")?"Loading ":"") + theEp.getName()));
		if (theEp == null) {
			// BAD
			buff.append("Error: Invalid episode chosen");
			buff.append(getStandardFooters());
			return buff.toString();
		}
		buff.append("<h3>Viewing <i>" + theEp.getName() + "</i></h3>\n");
		
		// save if requested to
		if (doSave) {
			currSeries.setLastPlay( epId );
			currSeries.updateLastView();
			mySettings.updateSeries(currSeries);
			buff.append("<p><i>Saved as last viewed!</i></p>\n");
		}				
		
		buff.append("<blockquote>\n<div>\n");
		if (request.isLocal()) {
			// maybe we want to watch it on the server computer!			
			String localLoc = mySettings.getLocalForEpisode(currSeries, theEp);
			if (!request.hasVar("local") && localLoc != null) {
				buff.append("<a href=\"?id="+seriesId+"&ep="+
						(epId)+"&local=1&save="+(doSave?1:0)+"\">Locally View "+theEp.getName()+"</a>\n");
			} else if (request.hasVar("local")) {
				if (loadLocalFile(localLoc))
					buff.append("Loading " + theEp.getName());				
				else buff.append("Could not load local file (" 
						+ localLoc + ") using player ("
						+ mySettings.getLocalPlayerLoc() + ").");
			} else {
				buff.append("Could not determine local file location.<br>");
				buff.append("<a href=\""+theEp.getLink()+"\">STREAM "+theEp.getName()+"</a>\n");
			}
		}		
		else {
			buff.append("<a href=\""+theEp.getLink()+"\">View "+theEp.getName()+"</a>\n");		
		}
		buff.append("</div>\n</blockquote>\n");	
		
		if (next != null) {
			// provide a convenient link to the next episode if it's available.
			// Also, if we're saving, then continue to do so. Otherwise, don't.
			buff.append("<br><br>\n<a href=\"?id="+seriesId+"&ep="+
					(epId+1)+(doSave?"&save=1":"")+"\">Continue to next: " + 
					next.getName() + "</a>\n");
		}
		buff.append(getNavigation("Back to <i>"+currSeries.getName()+"</i>",
				"../browse/?id="+currSeries.getId()));
		buff.append(getStandardFooters());		
		return buff.toString();
	}*/

	private boolean loadLocalFile(String localLoc) {
		try {
			Runtime.getRuntime().exec(
					new String[]{mySettings.getLocalPlayerLoc(),localLoc});
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

}
